#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Webhook模拟器接口
用于模拟微信客户输入并触发webhook回调
支持多用户ID模拟
"""

import time
import random
import string
from datetime import datetime
from flask import Blueprint, request, jsonify, current_app
from utils.logger import get_logger
from utils.webhook_client import WebhookClient
import json

webhook_simulator_bp = Blueprint('webhook_simulator', __name__)
logger = get_logger(__name__)


def generate_user_id(prefix="mock_user", length=8):
    """生成随机用户ID"""
    random_suffix = ''.join(random.choices(string.ascii_lowercase + string.digits, k=length))
    return f"{prefix}_{random_suffix}"


def validate_user_id(user_id):
    """验证用户ID格式"""
    if not user_id:
        return False, "用户ID不能为空"
    
    if len(user_id) < 3:
        return False, "用户ID长度不能少于3个字符"
    
    if len(user_id) > 64:
        return False, "用户ID长度不能超过64个字符"
    
    # 检查是否包含非法字符
    invalid_chars = ['<', '>', '&', '"', "'", '\\', '/', '|', '?', '*', ':', ';']
    for char in invalid_chars:
        if char in user_id:
            return False, f"用户ID不能包含字符: {char}"
    
    return True, ""


@webhook_simulator_bp.route('/webhook/simulate', methods=['POST'])
def simulate_customer_input():
    """模拟客户输入并触发webhook"""
    try:
        # 获取并解析请求体（更鲁棒，优先JSON，其次原始体解码）
        request_data = request.get_json(silent=True)
        if request_data is None:
            raw_body = request.get_data(cache=True) or b""
            # 强制使用UTF-8编码，避免Windows系统默认编码问题
            charset = (request.mimetype_params or {}).get('charset') or 'utf-8'
            if charset.lower() not in ['utf-8', 'utf8']:
                charset = 'utf-8'
            try:
                body_text = raw_body.decode(charset)
            except Exception:
                body_text = raw_body.decode('utf-8', errors='replace')
            try:
                request_data = json.loads(body_text)
            except Exception:
                request_data = None
        if not request_data:
            logger.warning("缺少请求体")
            return jsonify({
                "errcode": 41001,
                "errmsg": "missing request body"
            }), 400
        
        # 解析用户ID参数（优先级：URL参数 > 请求体参数 > 默认值）
        url_user_id = request.args.get('user_id')
        body_user_id = request_data.get('external_userid') or request_data.get('user_id')
        
        if url_user_id:
            external_userid = url_user_id
        elif body_user_id:
            external_userid = body_user_id
        else:
            # 生成随机用户ID
            external_userid = generate_user_id()
            logger.info(f"未指定用户ID，自动生成: {external_userid}")
        
        # 验证用户ID
        is_valid, error_msg = validate_user_id(external_userid)
        if not is_valid:
            return jsonify({
                "errcode": 41002,
                "errmsg": f"invalid user_id: {error_msg}"
            }), 400
        
        # 解析其他参数
        open_kfid = request_data.get('open_kfid', 'mock_kf_001')
        msgtype = request_data.get('msgtype', 'text')
        content = request_data.get('content', '你好，我需要帮助')
        
        logger.info(f"模拟客户输入 - 用户: {external_userid}, 类型: {msgtype}, 内容: {content}")
        
        # 获取数据管理器
        data_manager = current_app.data_manager
        
        # 生成消息ID
        msgid = f"mock_msg_{int(time.time())}"
        
        # 创建消息记录
        message = {
            "msgid": msgid,
            "open_kfid": open_kfid,
            "external_userid": external_userid,
            "send_time": int(datetime.now().timestamp()),
            "msgtype": msgtype,
            "direction": "receive"  # 接收方向
        }
        
        # 根据消息类型添加内容
        if msgtype == "text":
            message["text"] = {"content": content}
        elif msgtype == "image":
            message["image"] = {"media_id": content}
        elif msgtype == "voice":
            message["voice"] = {"media_id": content}
        elif msgtype == "file":
            message["file"] = {"media_id": content}
        elif msgtype == "link":
            message["link"] = {"url": content}
        
        # 保存消息
        data_manager.add_message(message)
        
        # 检查并创建会话（如果不存在），收到客户消息时更新活动时间
        session = data_manager.get_session(external_userid, open_kfid, update_activity=True)
        if not session:
            session_data = {
                "external_userid": external_userid,
                "open_kfid": open_kfid,
                "service_state": 0,  # 未处理状态
                "servicer_userid": "",
                "create_time": int(datetime.now().timestamp())
            }
            data_manager.update_session(external_userid, open_kfid, session_data)
            logger.info(f"创建新会话 - 用户: {external_userid}")
        
        # 发送webhook回调
        webhook_result = None
        if current_app.config.get('WEBHOOK_ENABLE_CALLBACK', True):
            try:
                webhook_client = WebhookClient(
                    webhook_url=current_app.config.get(
                        'WEBHOOK_URL', 'http://localhost:5005/webhook'),
                    token=current_app.config.get('WX_TOKEN', 'Sv3mVW1LOIU'),
                    encoding_aes_key=current_app.config.get(
                        'WX_AES_KEY', 'NgHrjQdRw46FQIyTedXxJu6GrjqcoewHWlCQVLA76Ai'),
                    corp_id=current_app.config.get(
                        'MOCK_WX_CORP_ID', 'wxc4c1ad1d26dc0daf')
                )
                
                webhook_result = webhook_client.send_webhook(
                    msg_type=msgtype,
                    content=content,
                    from_user=external_userid,
                    to_user="gh_test",
                    msg_id=msgid
                )
                
                if webhook_result.get('success'):
                    logger.info(f"Webhook回调发送成功 - 用户: {external_userid}")
                else:
                    logger.warning(
                        f"Webhook回调发送失败 - 用户: {external_userid}, "
                        f"错误: {webhook_result.get('error', 'unknown')}")
                    
            except Exception as e:
                logger.error(f"发送webhook回调异常: {e}")
                webhook_result = {'success': False, 'error': str(e)}
        
        # 更新统计信息
        data_manager.update_stats(success=True)
        
        logger.info(f"客户输入模拟成功 - 消息ID: {msgid}")
        
        response_data = {
            "errcode": 0,
            "errmsg": "ok",
            "msgid": msgid,
            "external_userid": external_userid,
            "session_state": data_manager.get_session(external_userid, open_kfid, update_activity=False).get('service_state', 0)
        }
        
        # 添加webhook回调结果
        if webhook_result:
            response_data["webhook_result"] = {
                "success": webhook_result.get('success', False),
                "status_code": webhook_result.get('status_code'),
                "error": webhook_result.get('error')
            }
        
        return jsonify(response_data)
        
    except Exception as e:
        logger.error(f"模拟客户输入失败: {e}")
        data_manager = current_app.data_manager
        data_manager.update_stats(success=False)
        
        return jsonify({
            "errcode": 500,
            "errmsg": "internal error"
        }), 500


@webhook_simulator_bp.route('/webhook/simulate/batch', methods=['POST'])
def simulate_batch_customer_input():
    """批量模拟多个客户输入"""
    try:
        # 获取请求体
        request_data = request.get_json()
        if not request_data:
            logger.warning("缺少请求体")
            return jsonify({
                "errcode": 41001,
                "errmsg": "missing request body"
            }), 400
        
        # 解析批量参数
        messages = request_data.get('messages', [])
        if not messages:
            return jsonify({
                "errcode": 41003,
                "errmsg": "missing messages array"
            }), 400
        
        # 验证消息数量限制
        max_messages = current_app.config.get('MAX_BATCH_MESSAGES', 10)
        if len(messages) > max_messages:
            return jsonify({
                "errcode": 41004,
                "errmsg": f"too many messages, max allowed: {max_messages}"
            }), 400
        
        results = []
        data_manager = current_app.data_manager
        
        for i, msg_data in enumerate(messages):
            try:
                # 解析单个消息参数
                external_userid = msg_data.get('external_userid') or msg_data.get('user_id')
                if not external_userid:
                    external_userid = generate_user_id()
                
                # 验证用户ID
                is_valid, error_msg = validate_user_id(external_userid)
                if not is_valid:
                    results.append({
                        "index": i,
                        "success": False,
                        "error": f"invalid user_id: {error_msg}"
                    })
                    continue
                
                open_kfid = msg_data.get('open_kfid', 'mock_kf_001')
                msgtype = msg_data.get('msgtype', 'text')
                content = msg_data.get('content', f'批量消息 {i+1}')
                
                # 生成消息ID
                msgid = f"mock_msg_{int(time.time())}_{i}"
                
                # 创建消息记录
                message = {
                    "msgid": msgid,
                    "open_kfid": open_kfid,
                    "external_userid": external_userid,
                    "send_time": int(datetime.now().timestamp()),
                    "msgtype": msgtype,
                    "direction": "receive"
                }
                
                # 根据消息类型添加内容
                if msgtype == "text":
                    message["text"] = {"content": content}
                elif msgtype == "image":
                    message["image"] = {"media_id": content}
                elif msgtype == "voice":
                    message["voice"] = {"media_id": content}
                elif msgtype == "file":
                    message["file"] = {"media_id": content}
                elif msgtype == "link":
                    message["link"] = {"url": content}
                
                # 保存消息
                data_manager.add_message(message)
                
                # 检查并创建会话
                session = data_manager.get_session(external_userid, open_kfid)
                if not session:
                    session_data = {
                        "external_userid": external_userid,
                        "open_kfid": open_kfid,
                        "service_state": 0,
                        "servicer_userid": "",
                        "create_time": int(datetime.now().timestamp())
                    }
                    data_manager.update_session(external_userid, open_kfid, session_data)
                
                # 发送webhook回调
                webhook_result = None
                if current_app.config.get('WEBHOOK_ENABLE_CALLBACK', True):
                    try:
                        webhook_client = WebhookClient(
                            webhook_url=current_app.config.get(
                                'WEBHOOK_URL', 'http://localhost:5005/webhook'),
                            token=current_app.config.get('WX_TOKEN', 'Sv3mVW1LOIU'),
                            encoding_aes_key=current_app.config.get(
                                'WX_AES_KEY', 'NgHrjQdRw46FQIyTedXxJu6GrjqcoewHWlCQVLA76Ai')
                        )
                        
                        webhook_result = webhook_client.send_webhook(
                            msg_type=msgtype,
                            content=content,
                            from_user=external_userid,
                            to_user="gh_test",
                            msg_id=msgid
                        )
                        
                    except Exception as e:
                        webhook_result = {'success': False, 'error': str(e)}
                
                results.append({
                    "index": i,
                    "success": True,
                    "msgid": msgid,
                    "external_userid": external_userid,
                    "webhook_success": webhook_result.get('success', False) if webhook_result else False
                })
                
            except Exception as e:
                results.append({
                    "index": i,
                    "success": False,
                    "error": str(e)
                })
        
        # 更新统计信息
        success_count = sum(1 for r in results if r.get('success', False))
        data_manager.update_stats(success=success_count > 0)
        
        logger.info(f"批量模拟完成 - 总数: {len(messages)}, 成功: {success_count}")
        
        return jsonify({
            "errcode": 0,
            "errmsg": "ok",
            "total": len(messages),
            "success_count": success_count,
            "results": results
        })
        
    except Exception as e:
        logger.error(f"批量模拟客户输入失败: {e}")
        return jsonify({
            "errcode": 500,
            "errmsg": "internal error"
        }), 500


@webhook_simulator_bp.route('/webhook/users', methods=['GET'])
def list_active_users():
    """获取活跃用户列表"""
    try:
        data_manager = current_app.data_manager
        
        # 获取所有会话
        sessions = data_manager.get_all_sessions()
        
        # 统计用户信息
        users = {}
        for session in sessions:
            user_id = session.get('external_userid')
            if user_id:
                if user_id not in users:
                    users[user_id] = {
                        "external_userid": user_id,
                        "session_count": 0,
                        "last_activity": 0,
                        "service_states": set()
                    }
                
                users[user_id]["session_count"] += 1
                users[user_id]["last_activity"] = max(
                    users[user_id]["last_activity"], 
                    session.get('create_time', 0)
                )
                users[user_id]["service_states"].add(session.get('service_state', 0))
        
        # 转换set为list以便JSON序列化
        for user in users.values():
            user["service_states"] = list(user["service_states"])
        
        return jsonify({
            "errcode": 0,
            "errmsg": "ok",
            "users": list(users.values()),
            "total": len(users)
        })
        
    except Exception as e:
        logger.error(f"获取用户列表失败: {e}")
        return jsonify({
            "errcode": 500,
            "errmsg": "internal error"
        }), 500


@webhook_simulator_bp.route('/webhook/users/<user_id>/messages', methods=['GET'])
def get_user_messages(user_id):
    """获取指定用户的消息历史"""
    try:
        # 验证用户ID
        is_valid, error_msg = validate_user_id(user_id)
        if not is_valid:
            return jsonify({
                "errcode": 41002,
                "errmsg": f"invalid user_id: {error_msg}"
            }), 400
        
        data_manager = current_app.data_manager
        
        # 获取用户消息
        messages = data_manager.get_messages_by_user(user_id)
        
        return jsonify({
            "errcode": 0,
            "errmsg": "ok",
            "external_userid": user_id,
            "messages": messages,
            "total": len(messages)
        })
        
    except Exception as e:
        logger.error(f"获取用户消息失败: {e}")
        return jsonify({
            "errcode": 500,
            "errmsg": "internal error"
        }), 500


@webhook_simulator_bp.route('/webhook/test', methods=['GET'])
def test_webhook():
    """测试webhook接口"""
    return jsonify({
        "errcode": 0,
        "errmsg": "ok",
        "message": "Webhook模拟器运行正常",
        "timestamp": datetime.now().isoformat()
    })


@webhook_simulator_bp.route('/webhook/verify', methods=['POST'])
def verify_webhook_url():
    """验证webhook URL"""
    try:
        request_data = request.get_json()
        if not request_data:
            return jsonify({
                "errcode": 41001,
                "errmsg": "missing request body"
            }), 400
        
        # 创建webhook客户端
        webhook_client = WebhookClient(
            webhook_url=current_app.config.get('WEBHOOK_URL', 'http://localhost:5005/webhook'),
            token=current_app.config.get('WX_TOKEN', 'Sv3mVW1LOIU'),
            encoding_aes_key=current_app.config.get('WX_AES_KEY', 'NgHrjQdRw46FQIyTedXxJu6GrjqcoewHWlCQVLA76Ai'),
            corp_id=current_app.config.get('MOCK_WX_CORP_ID', 'wxc4c1ad1d26dc0daf')
        )
        
        # 如果提供了echostr则使用，否则自动生成
        echostr = request_data.get('echostr')
        result = webhook_client.verify_webhook_url(echostr)
        
        return jsonify({
            "errcode": 0,
            "errmsg": "ok",
            "verify_result": result
        })
        
    except Exception as e:
        logger.error(f"验证webhook URL失败: {e}")
        return jsonify({
            "errcode": 500,
            "errmsg": "internal error"
        }), 500
